﻿using FlyingEye.Monitors.Models;
using FlyingEye.Monitors.Repositories;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Guids;
using Volo.Abp.Uow;

namespace FlyingEye.DeviceOpsServer
{
    /// <summary>
    /// 数据种子构造器
    /// </summary>
    public class MonitorServiceDataSeedContributor : IDataSeedContributor, ITransientDependency
    {
        private readonly IGuidGenerator _guidGenerator;

        public MonitorServiceDataSeedContributor(IGuidGenerator guidGenerator,
            IDeviceClientRepository deviceClientRepository,
            IReadNumericValueTaskRepository readValueDataTaskRepository,
            IReadStringValueTaskRepository readStringValueTaskRepository,
            IStringValueMonitorClientRepository stringValueMonitorClientRepository,
            IStringValueMonitorGroupRepository stringValueMonitorGroupRepository,
            INumericValueMonitorClientRepository numericValueMonitorClientRepository,
            INumericValueMonitorGroupRepository numericValueMonitorGroupRepository)
        {
            _guidGenerator = guidGenerator;
            _deviceClientRepository = deviceClientRepository;
            _readValueDataTaskRepository = readValueDataTaskRepository;
            _readStringValueTaskRepository = readStringValueTaskRepository;
            _stringValueMonitorClientRepository = stringValueMonitorClientRepository;
            _stringValueMonitorGroupRepository = stringValueMonitorGroupRepository;
            _numericValueMonitorClientRepository = numericValueMonitorClientRepository;
            _numericValueMonitorGroupRepository = numericValueMonitorGroupRepository;
        }

        private readonly IDeviceClientRepository _deviceClientRepository;

        private readonly IReadNumericValueTaskRepository _readValueDataTaskRepository;

        private readonly IReadStringValueTaskRepository _readStringValueTaskRepository;

        private readonly IStringValueMonitorClientRepository _stringValueMonitorClientRepository;

        private readonly IStringValueMonitorGroupRepository _stringValueMonitorGroupRepository;

        private readonly INumericValueMonitorClientRepository _numericValueMonitorClientRepository;

        private readonly INumericValueMonitorGroupRepository _numericValueMonitorGroupRepository;

        [UnitOfWork]
        public async Task SeedAsync(DataSeedContext context)
        {
            var deviceClient = await CrateDeviceClietnAsync();
            var readStringValueTask = await CreateReadStringValueTaskAsync(deviceClient.Id);
            var readNumericValueTask = await CreateReadNumericValueTaskAsync(deviceClient.Id);
            await CreateStringValueMonitorClientAsync(readStringValueTask.Id);
            await CreateStringValueMonitorGroupAsync(readStringValueTask.Id);
            await CreateNumericValueMonitorClientAsync(readNumericValueTask.Id);
            await CreateNumericValueMonitorGroupAsync(readNumericValueTask.Id);
            await Task.CompletedTask;
        }

        private async Task<NumericValueMonitorGroupModel> CreateNumericValueMonitorGroupAsync(Guid readValueDataTaskId)
        {
            var model = await _numericValueMonitorGroupRepository.FindAsync(item => item.GroupName == "TestNumericValueMonitorGroupName");

            if (model == null)
            {
                return await _numericValueMonitorGroupRepository.InsertAsync(
                    new NumericValueMonitorGroupModel(readValueDataTaskId, "TestNumericValueMonitorGroupName"));
            }

            return model;
        }

        private async Task<NumericValueMonitorClientModel> CreateNumericValueMonitorClientAsync(Guid readValueDataTaskId)
        {
            var model = await _numericValueMonitorClientRepository.FindAsync(item => item.ClientName == "TestNumericValueMonitorClientName");

            if (model == null)
            {
                return await _numericValueMonitorClientRepository.InsertAsync(
                    new NumericValueMonitorClientModel(readValueDataTaskId, "TestNumericValueMonitorClientName"));
            }

            return model;
        }

        private async Task<StringValueMonitorGroupModel> CreateStringValueMonitorGroupAsync(Guid readStringValueTaskId)
        {
            var model = await _stringValueMonitorGroupRepository.FindAsync(item => item.GroupName == "TestStringValueMonitorGroupName");

            if (model == null)
            {
                return await _stringValueMonitorGroupRepository.InsertAsync(
                    new StringValueMonitorGroupModel(readStringValueTaskId, "TestStringValueMonitorGroupName"));
            }

            return model;
        }

        private async Task<StringValueMonitorClientModel> CreateStringValueMonitorClientAsync(Guid readStringValueTaskId)
        {
            var model = await _stringValueMonitorClientRepository.FindAsync(item => item.ClientName == "TestStringValueMonitorClientName");

            if (model == null)
            {
                return await _stringValueMonitorClientRepository.InsertAsync(
                    new StringValueMonitorClientModel(readStringValueTaskId, "TestStringValueMonitorClientName"));
            }

            return model;
        }

        private async Task<ReadNumericValueTaskModel> CreateReadNumericValueTaskAsync(Guid deviceClientId)
        {
            var model = await _readValueDataTaskRepository.FindAsync(item => item.TaskName == "TestReadNumericValueTaskName");

            if (model == null)
            {
                return await _readValueDataTaskRepository.InsertAsync(new ReadNumericValueTaskModel(
                    deviceClientId,
                    "TestReadNumericValueTaskName",
                    "TestDeviceName",
                    "M100",
                    "float",
                    2000,
                    true
               ));
            }

            return model;
        }

        private async Task<ReadStringValueTaskModel> CreateReadStringValueTaskAsync(Guid deviceClientId)
        {
            var model = await _readStringValueTaskRepository.FindAsync(item => item.TaskName == "TestReadStringValueTaskName");

            if (model == null)
            {
                return await _readStringValueTaskRepository.InsertAsync(new ReadStringValueTaskModel(
                    deviceClientId,
                    "TestReadStringValueTaskName",
                    "TestDeviceName",
                    "M200",
                    5,
                    2000,
                    true));
            }

            return model;
        }

        private async Task<DeviceClientModel> CrateDeviceClietnAsync()
        {
            var model = await _deviceClientRepository.FindAsync(item => item.ResourceId == "TestDeviceClient");

            if (model == null)
            {
                return await _deviceClientRepository.InsertAsync(new DeviceClientModel(9999, "TestProcessName", "TestDeviceClient"));
            }

            return model;
        }
    }
}
